package com.meilai.project.service.business.saleOrder.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilai.project.dto.base.ApiResult;
import com.meilai.project.dto.business.intentionScheme.*;
import com.meilai.project.dto.business.saleOrder.SaleIntentionOrderDTO;
import com.meilai.project.dto.business.saleOrder.SaleIntentionOrderSaveDTO;
import com.meilai.project.dto.business.saleOrder.SaleMapSearchDTO;
import com.meilai.project.dto.media.MediaPointDTO;
import com.meilai.project.entity.business.building.BuildingArea;
import com.meilai.project.entity.business.customer.CustomerInfo;
import com.meilai.project.entity.business.saleOrder.SaleIntentionOrder;
import com.meilai.project.entity.business.saleOrder.SaleIntentionOrderDaterange;
import com.meilai.project.entity.media.MediaPoint;
import com.meilai.project.entity.media.MediaPointExt;
import com.meilai.project.mapper.business.building.BuildingAreaMapper;
import com.meilai.project.mapper.business.customer.CustomerInfoMapper;
import com.meilai.project.mapper.business.media.MediaPointMapper;
import com.meilai.project.mapper.business.media.MediaTypeMapper;
import com.meilai.project.mapper.business.saleOrder.SaleIntentionOrderDaterangeMapper;
import com.meilai.project.mapper.business.saleOrder.SaleIntentionOrderMapper;
import com.meilai.project.service.business.saleOrder.SaleIntentionOrderService;
import com.meilai.project.util.DistanceUtil;
import com.meilai.project.util.entity.PointRange;
import com.meilai.project.vo.business.media.MediaTypeVO;
import com.meilai.project.vo.business.saleOrder.SaleIntentionOrderVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ykb
 * @since 2022-03-05
 */
@Service
public class SaleIntentionOrderServiceImpl extends ServiceImpl<SaleIntentionOrderMapper, SaleIntentionOrder> implements SaleIntentionOrderService {

	@Autowired
	private SaleIntentionOrderDaterangeMapper saleIntentionOrderDaterangeMapper;

	@Autowired
	private BuildingAreaMapper buildingAreaMapper;

	@Autowired
	private MediaPointMapper mediaPointMapper;
	@Autowired
	private MediaTypeMapper mediaTypeMapper;
	@Autowired
	private CustomerInfoMapper customerInfoMapper;


	@Override
	public List<BuildingPointVO> search(SaleMapSearchDTO searchDTO) {
		//查询楼盘列表（通过：选择的资源类型、辐射半径、位置、行政区四个条件筛选）
		List<BuildingArea> filterBuildingAreaList = getFilterBuildingAreaList(searchDTO);

		//根据点位类型，楼层，A,B类型，筛选出来的buildId，禁投行业，区域，所有未锁定的point_id 作为filter,
		//所输入的地址半径作为查询条件，查出所有的点位(这时候是所有未锁定的点位)
		List<MediaPointExt> pointList = getMeetConditionPoint(searchDTO, filterBuildingAreaList);

		//返回结果(building - type - count - detail)
		List<BuildingPointVO> result = new ArrayList<>();
		if (CollUtil.isEmpty(pointList)) {
			return result;
		}

		return assemble(pointList);
	}

	private List<MediaPointExt> getMeetConditionPoint(
			SaleMapSearchDTO searchDTO, List<BuildingArea> filterBuildingAreaList) {
		PointProcessSearchDTO temp = new PointProcessSearchDTO();
		BeanUtils.copyProperties(searchDTO, temp);
		return mediaPointMapper.listByCondition(temp, null, filterBuildingAreaList);
	}

	public List<BuildingPointVO> assemble(List<MediaPointExt> pointList) {
		List<BuildingPointVO> result = new ArrayList<>();
		//获取media——type
		List<MediaTypeVO> mediaTypeVOList= mediaTypeMapper.getMediaTypes();
		Map<Long, String> mediaTypeMap = mediaTypeVOList.stream().collect(Collectors.toMap(mediaTypeVO -> mediaTypeVO.getId(),mediaTypeVO -> mediaTypeVO.getName()));
		//获取所有点位信息
		List<com.meilai.project.vo.business.media.MediaPointVO> listMediaPoint = mediaPointMapper.listMediaPoint(new MediaPointDTO());
		Map<Long, List<com.meilai.project.vo.business.media.MediaPointVO>> total_building2PointListMap = listMediaPoint.stream().filter(mp -> null != mp.getBuilding_area_id()).collect(Collectors.groupingBy(com.meilai.project.vo.business.media.MediaPointVO::getBuilding_area_id));

		Map<Long, List<MediaPointExt>> building2PointListMap = pointList.stream().collect(Collectors.groupingBy(MediaPoint::getBuilding_area_id));
		List<Long> buildIdList = new ArrayList<>(building2PointListMap.keySet());
		List<BuildingArea> buildingAreaList = buildingAreaMapper.selectBatchIds(buildIdList);
		for (BuildingArea buildingArea : buildingAreaList) {
			BuildingPointVO item = new BuildingPointVO();
			item.setId(buildingArea.getId());
			item.setName(buildingArea.getName());
			item.setAddress(buildingArea.getAddress());
			item.setLatitude(buildingArea.getLat());
			item.setLongitude(buildingArea.getLng());

			//包含的所有点位信息
			List<com.meilai.project.vo.business.media.MediaPointVO> total_mediaPoints = total_building2PointListMap.get(buildingArea.getId());
			Map<Long, List<com.meilai.project.vo.business.media.MediaPointVO>> total_pointTypeMap = total_mediaPoints.stream().filter(mp -> null != mp.getMedia_type_id()).collect(Collectors.groupingBy(com.meilai.project.vo.business.media.MediaPointVO::getMedia_type_id));
			//包含的mediaPoints
			List<MediaPointExt> mediaPoints = building2PointListMap.get(buildingArea.getId());
			Map<Long, List<MediaPointExt>> pointTypeMap = mediaPoints.stream().filter(mp -> null != mp.getMedia_type_id()).collect(Collectors.groupingBy(MediaPoint::getMedia_type_id));
			//创建这个building下的各类型的点位信息
			Map<Long, PointTypeCountVO> pointTypeCountVOMap = new LinkedHashMap<>();
			item.setPointTypeCountVOMap(pointTypeCountVOMap);
			List<PointTypeCountVO> pointTypeCountVOList = new ArrayList<>();
			item.setPointTypeCountVOList(pointTypeCountVOList);
			Set<Long> pointTypeIdList = pointTypeMap.keySet();
			for (Long pointTypeId : pointTypeIdList) {
				PointTypeCountVO itemVO = new PointTypeCountVO();
				itemVO.setPoint_type_id(pointTypeId);
				itemVO.setPoint_type_name(mediaTypeMap.get(pointTypeId));
				pointTypeCountVOMap.put(pointTypeId, itemVO);
				pointTypeCountVOList.add(itemVO);

				//创建这个building下这个point_type的media_point列表
				List<MediaPointSimpleVO> mediaPointSimpleVOList = new ArrayList<>();
				itemVO.setMediaPointList(mediaPointSimpleVOList);
				List<MediaPointExt> subMediaList = pointTypeMap.get(pointTypeId);
				if (CollUtil.isEmpty(subMediaList)) {
					itemVO.setPoint_type_count(0);
				} else {
					for (MediaPointExt mediaPoint : subMediaList) {
						MediaPointSimpleVO mediaPointSimpleVO = MediaPointSimpleVO.parseFrom(mediaPoint);
						mediaPointSimpleVOList.add(mediaPointSimpleVO);
					}
					itemVO.setPoint_type_count(mediaPointSimpleVOList.size());
				}

				//补充这个building下这个point_type的点位总数
				List<com.meilai.project.vo.business.media.MediaPointVO> total_subMediaList = total_pointTypeMap.get(pointTypeId);
				if(CollUtil.isEmpty(total_subMediaList)){
					itemVO.setPoint_type_total_count(0);
				}else {
					itemVO.setPoint_type_total_count(total_subMediaList.size());
				}
			}
			result.add(item);
		}
		return result;
	}

	private List<BuildingArea> getFilterBuildingAreaList(SaleMapSearchDTO searchDTO) {
		List<LocationInfo> locationList=searchDTO.getPositionLocationList();
		List<BuildingArea> buildFilterList = new ArrayList<>();
		if (CollUtil.isNotEmpty(locationList)) {
			Integer buildingRadius = searchDTO.getPositionRadius();
			List<PointRange> pointRanges = new ArrayList<>();
			for (LocationInfo locationInfo : locationList) {
				PointRange aroundRange = DistanceUtil.getAroundRange(locationInfo.getLat().doubleValue(),
						locationInfo.getLng().doubleValue(), buildingRadius);
				pointRanges.add(aroundRange);
			}
			List<BuildingArea> buildingAreaList =
					buildingAreaMapper.listBySaleCondition(searchDTO.getPcaList(), pointRanges,searchDTO.getBuildingTypeIdList());
			buildFilterList.addAll(buildingAreaList);
		}
		return buildFilterList;
	}

	@Override
	public Page<SaleIntentionOrderVO> selectPageList(Integer current_page, Integer page_size, String beginDate, String endDate, SaleIntentionOrderDTO searchDTO) {
		Page<SaleIntentionOrderVO> page = new Page<>(current_page, page_size);
		List<SaleIntentionOrderVO> list = baseMapper.selectPageList(page, beginDate, endDate,searchDTO);
		return page.setRecords(list);
	}

	@Override
	public List<CustomerInfo> listCustomerOfSale(Long sale_id) {

		return customerInfoMapper.selectList(new QueryWrapper<CustomerInfo>().isNull("deleted_at").eq("status",1).eq("maintenance_staff_id",sale_id));
	}


	@Override
	@Transactional(rollbackFor = Throwable.class)
	public ApiResult<SaleIntentionOrderSaveDTO> save(SaleIntentionOrderSaveDTO dto) {
		List<SaleIntentionOrderDTO> orderList = dto.getOrderList();
		if(CollUtil.isNotEmpty(orderList)){
			for (SaleIntentionOrderDTO order: orderList) {
				SaleIntentionOrder saleIntentionOrder = new SaleIntentionOrder();
				BeanUtils.copyProperties(order, saleIntentionOrder);
				saleIntentionOrder.setSale_id(dto.getSale_id());
				saleIntentionOrder.setCustomer_id(dto.getCustomer_id());
				baseMapper.insert(saleIntentionOrder);
				SaleIntentionOrderDaterange daterange = new SaleIntentionOrderDaterange();
				daterange.setStart_at(dto.getBeginDate());
				daterange.setEnd_at(dto.getEndDate());
				daterange.setSale_intention_order_id(saleIntentionOrder.getId());
				saleIntentionOrderDaterangeMapper.insert(daterange);
			}
		}

		return ApiResult.ok(dto);
	}



}
